package com.rustic.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.xy.commons.exception.JzRuntimeException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rustic.server.dao.UserLikeLinkDao;
import com.rustic.server.enums.LinkType;
import com.rustic.server.po.Attractions;
import com.rustic.server.po.EventActivity;
import com.rustic.server.po.Food;
import com.rustic.server.po.Rustic;
import com.rustic.server.po.TravelPlan;
import com.rustic.server.po.UserLikeLink;
import com.rustic.server.query.UserLikeLinkAdminListQuery;
import com.rustic.server.query.UserLikeLinkUserListQuery;
import com.rustic.server.service.AttractionsService;
import com.rustic.server.service.CommentService;
import com.rustic.server.service.EventActivityService;
import com.rustic.server.service.FoodService;
import com.rustic.server.service.RusticService;
import com.rustic.server.service.TravelPlanService;
import com.rustic.server.service.UserLikeLinkService;
import com.rustic.server.vo.list.UserLikeLinkAdminListVO;
import com.rustic.server.vo.list.UserLikeLinkWebListVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * UserLikeLink对应的服务类实现
 *
 * @author auto
 */

@Service
public class UserLikeLinkServiceImpl extends ServiceImpl<UserLikeLinkDao, UserLikeLink> implements UserLikeLinkService {

    @Autowired
    private CommentService commentService;

    @Autowired
    private RusticService rusticService;

    @Autowired
    private AttractionsService attractionsService;

    @Autowired
    private EventActivityService eventActivityService;

    @Autowired
    private FoodService foodService;

    @Autowired
    private TravelPlanService travelPlanService;

    @Override
    public List<UserLikeLink> listByIdIn(List<Integer> idList) {
        if (CollUtil.isEmpty(idList)) {
            return new ArrayList<>();
        }
        return this.listByIds(idList);
    }

    @Override
    public Map<Integer, UserLikeLink> mapByIdIn(List<Integer> idList) {
        List<UserLikeLink> userLikeLinkList = this.listByIdIn(idList);
        return userLikeLinkList.stream().collect(Collectors.toMap(UserLikeLink::getId, b -> b));
    }

    @Override
    public LambdaQueryWrapper<UserLikeLink> toAdminListWrapper(UserLikeLinkAdminListQuery query) {
        LambdaQueryWrapper<UserLikeLink> queryWrapper = new LambdaQueryWrapper<>();
        //FIXME 根据需要修改搜索条件
        queryWrapper.eq(query.getTargetId() > 0, UserLikeLink::getTargetId, query.getTargetId());
        queryWrapper.eq(query.getUserId() > 0, UserLikeLink::getUserId, query.getUserId());
        queryWrapper.eq(query.getType() > 0, UserLikeLink::getType, query.getType());
        queryWrapper.gt(query.getStartCreateTime() != null, UserLikeLink::getCreateTime, query.getStartCreateTime());
        queryWrapper.lt(query.getEndCreateTime() != null, UserLikeLink::getCreateTime, query.getEndCreateTime());
        return queryWrapper;
    }

    @Override
    public List<UserLikeLinkAdminListVO> toAdminListVo(List<UserLikeLink> userLikeLinkList) {
        List<UserLikeLinkAdminListVO> results = new ArrayList<>();
        for (UserLikeLink userLikeLink : userLikeLinkList) {
            UserLikeLinkAdminListVO userLikeLinkAdminListVO = new UserLikeLinkAdminListVO(userLikeLink);
            results.add(userLikeLinkAdminListVO);
        }
        return results;
    }

    @Override
    public List<UserLikeLinkWebListVO> toWebListVo(List<UserLikeLink> userLikeLinkList) {
        // 乡村
        List<Integer> rusticIdList = userLikeLinkList.stream()
                .map(UserLikeLink::getRusticId)
                .collect(Collectors.toList());
        Map<Integer, Rustic> rusticMap = rusticService.mapByIdIn(rusticIdList);
        // 活动
        List<Integer> activityIdList = userLikeLinkList.stream()
                .filter(userLikeLink -> userLikeLink.getType() == LinkType.ACTIVITY.getValue())
                .map(UserLikeLink::getTargetId)
                .collect(Collectors.toList());
        Map<Integer, EventActivity> activityMap = eventActivityService.mapByIdIn(activityIdList);
        // 景点
        List<Integer> attractionsIdList = userLikeLinkList.stream()
                .filter(userLikeLink -> userLikeLink.getType() == LinkType.ATTRACTIONS.getValue())
                .map(UserLikeLink::getTargetId)
                .collect(Collectors.toList());
        Map<Integer, Attractions> attractionsMap = attractionsService.mapByIdIn(attractionsIdList);
        // 美食
        List<Integer> foodIdList = userLikeLinkList.stream()
                .filter(userLikeLink -> userLikeLink.getType() == LinkType.FOOD.getValue())
                .map(UserLikeLink::getTargetId)
                .collect(Collectors.toList());
        Map<Integer, Food> foodMap = foodService.mapByIdIn(foodIdList);
        // 攻略
        List<Integer> travelPlanIdList = userLikeLinkList.stream()
                .filter(userLikeLink -> userLikeLink.getType() == LinkType.TRAVEL_PLAN.getValue())
                .map(UserLikeLink::getTargetId)
                .collect(Collectors.toList());
        Map<Integer, TravelPlan> travelPlanMap = travelPlanService.mapByIdIn(travelPlanIdList);

        return userLikeLinkList.stream().map(item -> {
            UserLikeLinkWebListVO userLikeLinkVO = new UserLikeLinkWebListVO(item);
            Rustic rustic = rusticMap.get(item.getRusticId());
            userLikeLinkVO.setRusticName(rustic != null ? rustic.getName() : "");
            if (item.getType() == LinkType.ACTIVITY.getValue()) {
                EventActivity eventActivity = activityMap.get(item.getTargetId());
                if (eventActivity != null) {
                    userLikeLinkVO.setName(eventActivity.getName());
                    userLikeLinkVO.setCover(eventActivity.getCover());
                }
            } else if (item.getType() == LinkType.ATTRACTIONS.getValue()) {
                Attractions attractions = attractionsMap.get(item.getTargetId());
                if (attractions != null) {
                    userLikeLinkVO.setName(attractions.getName());
                    userLikeLinkVO.setCover(attractions.getCover());
                }
            } else if (item.getType() == LinkType.FOOD.getValue()) {
                Food food = foodMap.get(item.getTargetId());
                if (food != null) {
                    userLikeLinkVO.setName(food.getName());
                    userLikeLinkVO.setCover(food.getCover());
                }
            } else if (item.getType() == LinkType.TRAVEL_PLAN.getValue()) {
                TravelPlan travelPlan = travelPlanMap.get(item.getTargetId());
                if (travelPlan != null) {
                    userLikeLinkVO.setName(travelPlan.getName());
                    userLikeLinkVO.setCover(travelPlan.getCover());
                }
            } else if (item.getType() == LinkType.RUSTIC.getValue()) {
                if (rustic != null) {
                    userLikeLinkVO.setName(rustic.getName());
                    userLikeLinkVO.setCover(rustic.getCover());
                    userLikeLinkVO.setIntroduce(rustic.getBriefIntro());
                }
            }
            return userLikeLinkVO;
        }).collect(Collectors.toList());
    }

    @Override
    public LambdaQueryWrapper<UserLikeLink> toWebListWrapper(UserLikeLinkUserListQuery query, int userId) {
        LambdaQueryWrapper<UserLikeLink> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserLikeLink::getUserId, userId);
        wrapper.eq(query.getType() > 0, UserLikeLink::getType, query.getType());
        wrapper.gt(query.getStartCreateTime() != null, UserLikeLink::getCreateTime, query.getStartCreateTime());
        wrapper.lt(query.getEndCreateTime() != null, UserLikeLink::getCreateTime, query.getEndCreateTime());
        return wrapper;
    }

    @Override
    public Map<Integer, Long> mapByTargetIdAndType(List<Integer> targetIdList, LinkType type) {
        if (CollUtil.isEmpty(targetIdList)) {
            return new HashMap<>();
        }
        List<UserLikeLink> list = this.list(new LambdaQueryWrapper<UserLikeLink>()
                .eq(UserLikeLink::getType, type.getValue())
                .in(UserLikeLink::getTargetId, targetIdList));
        // 使用流来转换和收集结果
        return list.stream()
                .collect(Collectors.groupingBy(
                        UserLikeLink::getTargetId, // 分组依据：targetId
                        Collectors.counting()       // 收集器：计数
                ));
    }

    @Override
    public Long getTargetAndType(int targetId, LinkType type) {
        return this.count(new LambdaQueryWrapper<UserLikeLink>()
                .eq(UserLikeLink::getTargetId, targetId)
                .eq(UserLikeLink::getType, type.getValue()));
    }

    @Override
    public Map<Integer, UserLikeLink> mapByUserTargetAndType(List<Integer> targetIdList, LinkType type, int userId) {
        if (CollUtil.isEmpty(targetIdList)) {
            return new HashMap<>();
        }
        // 要是用户没有登录就不用查询了
        if (userId == 0) {
            return new HashMap<>();
        }
        List<UserLikeLink> likeLinks = this.list(new LambdaQueryWrapper<UserLikeLink>()
                .in(UserLikeLink::getTargetId, targetIdList)
                .eq(UserLikeLink::getType, type.getValue())
                .eq(UserLikeLink::getUserId, userId));
        return likeLinks.stream().collect(Collectors.toMap(UserLikeLink::getTargetId, b -> b));
    }

    @Override
    public UserLikeLink getByUserTargetAndType(int userId, int targetId, int type) {
        return this.getOne(new LambdaQueryWrapper<UserLikeLink>()
                .eq(UserLikeLink::getUserId, userId)
                .eq(UserLikeLink::getTargetId, targetId)
                .eq(UserLikeLink::getType, type));
    }

    @Override
    public String addOrDelLike(int userId, int targetId, int type) {
        UserLikeLink likeLink = new UserLikeLink();
        // 校验是否已经点赞
        UserLikeLink userLikeLink = this.getByUserTargetAndType(userId, targetId, type);
        if (userLikeLink != null) {
            this.removeById(userLikeLink.getId());
            return "成功取消点赞";
        }
        int rusticId = commentService.addInteractionDataCheck(targetId, type);
        // 添加数据
        likeLink.setRusticId(rusticId);
        likeLink.setUserId(userId);
        likeLink.setType(type);
        likeLink.setTargetId(targetId);
        this.save(likeLink);
        return "点赞成功";
    }
}
